//  -----------------------------------------------------------------------------------------------//
//   This file is part of SvnExternalUpdater                                                               //
//   Copyright (C)2008 Romain Verdier ( romain@codingly.com )                                      //
//                                                                                                 //
//   This program is free software; you can redistribute it and/or modify it under the terms       //
//   of the GNU General Public License as published by the Free Software Foundation; either        //
//   version 2 of the License, or (at your option) any later version. This program is distributed  //
//   in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied        //
//   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public  //
//   License for more details.                                                                     //
//                                                                                                 //
//   You should have received a copy of the GNU General Public License along with this program; if //
//   not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. or  //
//   see http://www.fsf.org/licensing/licenses/gpl.html                                            //
//  -----------------------------------------------------------------------------------------------//
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using Codingly.SvnExternalUpdater.Layout;
using Codingly.SvnExternalUpdater.Presenters;
using Codingly.SvnExternalUpdater.Properties;

namespace Codingly.SvnExternalUpdater.Views
{
	public partial class ProjectView : UserControl, IProjectView
	{
		private readonly LayoutManager layoutManager;

		protected SynchronizationContext syncronizationContext;

		private bool expanded = true;
		private bool? isUpToDate;
		private string placeHolderKey;

		public ProjectView(LayoutManager layoutManager, SynchronizationContext syncronizationContext)
		{
			InitializeComponent();
			this.layoutManager = layoutManager;
			this.syncronizationContext = syncronizationContext;
		}

		public void ClearViews()
		{
			this.panelExternals.Controls.Clear();
			UpdateHeight();
		}

		public void LoadProject()
		{
			UpdateHeight();
		}

		public void SetHeader(string projectName, string projectPath, string projectUrl)
		{
			this.syncronizationContext.Post(delegate
			                                {
			                                	this.labelProjectName.Text = projectName;
			                                	this.labelPath.Text = projectPath;
			                                	this.labelUrl.Text = projectUrl;
			                                }, null);
		}

		public void ShowWaitingIndicator(bool show)
		{
			this.pictureBoxWaitingIndicator.Visible = show;
		}

		private void UpdateHeight()
		{
			this.panelExternals.Height = 0;
			if (this.expanded)
			{
				this.panelExternals.Height = 26*this.panelExternals.Controls.Count;
			}
			Height = 50 + this.panelExternals.Height;
		}

		private void UpdateImage()
		{
			this.pictureBoxExpandCollapse.Image = this.expanded ? Resources.Minus : Resources.Plus;
		}

		private void labelPath_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
		{
			Presenter.ExplorePath();
		}

		private void pictureBoxExpandCollapse_Click(object sender, EventArgs e)
		{
			this.expanded = !this.expanded;
			UpdateImage();
			UpdateHeight();
		}

		private void pictureBoxUpdate_Click(object sender, EventArgs e)
		{
			Presenter.Update();
		}

		private void ProjectView_Load(object sender, EventArgs e)
		{
		}

		#region IProjectView Members

		public ProjectPresenter Presenter { set; get; }

		public string ProjectName
		{
			set { this.syncronizationContext.Post(delegate { this.labelProjectName.Text = value; }, null); }
		}

		public string ProjectPath
		{
			set { this.syncronizationContext.Post(delegate { this.labelPath.Text = value; }, null); }
		}

		public string ProjectUrl
		{
			set { this.syncronizationContext.Post(delegate { this.labelUrl.Text = value; }, null); }
		}

		public bool IsUpToDate
		{
			set
			{
				this.syncronizationContext.Post(delegate
				                                {
				                                	this.pictureBoxUpdate.Enabled = !value;
				                                	this.pictureBoxUpdate.Image = value ? Resources.UpdateGrey : Resources.UpdateGreen;
				                                	this.labelProjectName.ForeColor = value ? Color.DarkGreen : Color.DarkRed;
				                                	if (this.isUpToDate == null || value != this.isUpToDate)
				                                	{
				                                		this.panelBackground.BackgroundImage = value ? Resources.GreenBackground : Resources.RedBackground;
				                                	}
				                                	this.isUpToDate = value;
				                                }, null);
			}
		}

		public void ShowWaitingIndicator()
		{
			this.syncronizationContext.Post(delegate { ShowWaitingIndicator(true); }, null);
		}

		public void ShowErrorMessage(string message)
		{
			MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
		}

		public void HideWaitingIndicator()
		{
			this.syncronizationContext.Post(delegate { ShowWaitingIndicator(false); }, null);
		}

		public string PlaceHolderKey
		{
			get { return this.placeHolderKey; }
			set
			{
				this.placeHolderKey = value;
				this.layoutManager.RegisterPlaceHolder(value, this);
			}
		}

		void IViewPlaceHolder.SuspendLayout()
		{
			this.panelExternals.SuspendLayout();
		}

		public void AppendView(object view)
		{
			this.syncronizationContext.Post(delegate
			                                {
			                                	var control = view as Control;
			                                	if (control != null)
			                                	{
			                                		this.panelExternals.Controls.Add(control);
			                                		control.Dock = DockStyle.Top;
			                                		UpdateHeight();
			                                	}
			                                }, null);
		}

		public void RemoveView(object view)
		{
			this.syncronizationContext.Post(delegate
			                                {
			                                	var control = view as Control;
			                                	if (this.panelExternals.Controls.Contains(control))
			                                	{
			                                		this.panelExternals.Controls.Remove(control);
			                                		UpdateHeight();
			                                	}
			                                }, null);
		}

		void IViewPlaceHolder.ResumeLayout()
		{
			this.panelExternals.ResumeLayout();
		}

		public void Append(string placeHolderKey)
		{
			this.layoutManager.Append(placeHolderKey, this);
		}

		public void Remove(string placeHolderKey)
		{
			this.layoutManager.Remove(placeHolderKey, this);
		}

		#endregion
	}
}